#include "CardManager.h"
#include <time.h>
#include <stdlib.h>
#include "LogEx.h"
using namespace std;

const unsigned char g_cards[Card::E_Max_Count] =
{
    0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,   //方块 A 2 - K
    0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,   //梅花 A 2 - K
    0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,   //红桃 A 2 - K
    0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,   //黑桃 A 2 - K
    0x41,0x42,                                                          //小王 大王
};

CardManager::CardManager(int count)
{
	m_total = count * Card::E_Max_Count;
	Shuffle();
}

CardManager::~CardManager()
{
}

void CardManager::Clean()
{
	Shuffle();
}

//#define _MAKE_CARDS_FOR_TEST_
void CardManager::Shuffle()
{
	m_left = m_total;
	m_cards.clear();
#ifdef _MAKE_CARDS_FOR_TEST_
    int count = m_total / Card::E_Max_Count;
	for( int i=0; i<count; ++i )
	{
        /*
        //for(char card=0x0D; card>=0x01; --card)
        for(char card=0x01; card<=0x0D; ++card)
        {
            for(char j=0; j<4; ++j)
            {
                char cd = (j << 4) + card;
			    m_cards.push_back( cd );
            }
        }
        */
        for(char j=0; j<4; ++j)
        for(char card=0x01; card<=0x0D; ++card)
        {
            char cd = (j << 4) + card;
			m_cards.push_back( cd );
        }
		m_cards.push_back( 0x41 );
		m_cards.push_back( 0x42 );
    }
    char strcards[512] = {0};
    vector<unsigned char>::iterator it = m_cards.begin();
    for(; it != m_cards.end(); ++it )
    {
        char _tmp[8] = {0};
        sprintf( _tmp, "0x%X,", *it);
        strcat( strcards, _tmp );
    }
    LOG_WARN("======> %s", strcards);
#else
	int count = m_total / Card::E_Max_Count;
	for( int i=0; i<count; ++i )
	{
		for( int j=0; j<Card::E_Max_Count; ++j )
		{
			m_cards.push_back( g_cards[j] );
		}
	}
#endif
	
	m_seed = (int)time(NULL);
	//srand( m_seed );
}

unsigned char CardManager::Deal()
{
	if( m_left <= 0 )
	{
		return Card::E_Invalid_Card;
	}
#ifdef _MAKE_CARDS_FOR_TEST_
    int idx = 0;
#else
	int idx = rand() % m_left;
#endif

	unsigned char card = m_cards[ idx ];

	// swap
	unsigned char tmp = m_cards[ m_left-1 ];
	m_cards[ m_left-1 ] = card;
	m_cards[ idx ] = tmp;

	--m_left;

	return card;
}

unsigned char CardManager::RandCard(bool hasKing)
{
    int n = Card::E_Max_Count;
    if( !hasKing )
    {
        n -= 2;
    }
    return g_cards[ rand() % n ];
}

